<template>
  <div class="layric-box">
    <div class="lyric_area">
      <ul id="lyric" ref="lyricUl" v-html="lyrivHtml"></ul>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    layricTxt: {
      type: String,
      default: "",
    },
  },
  computed: {
    layricobj() {
      return this.layricTxt || "";
    },
  },
  watch: {
    layricobj() {
      this.createLrcObj(this.layricobj);
    },
  },
  data() {
    return {
      oLRC: {
        ti: "", //歌曲名
        ar: "", //演唱者
        al: "", //专辑名
        by: "", //歌词制作人
        offset: 0, //时间补偿值，单位毫秒，用于调整歌词整体位置
        ms: [], //歌词数组{t:时间,c:歌词}
      },
      lyrivHtml: "",
      lineNo: 0, //当前行
      C_pos: 6, //C位
      offset: -20, //滚动距离（应等于行高）
      lyricUl: null, //歌词框
    };
  },
  mounted() {
    this.lyricUl = this.$refs.lyricUl;
  },
  methods: {
    //   音频播放，歌词滚动
    lyricGo(num) {
      if (!this.layricTxt) return;
      if (this.lineNo == this.oLRC.ms.length) return;
      if (parseFloat(this.oLRC.ms[this.lineNo].t) <= num) {
        this.lineHigh(); //高亮当前行
        this.lineNo++;
      }
    },
    // 歌词滚动进度
    lineHigh(flag) {
      if (flag) {
        this.lyricUl.style.transform =
          "translateY(" + (this.lineNo - this.C_pos) * this.offset + "px)"; //整体向上滚动一行高度
      } else {
        if (this.lineNo > this.C_pos) {
          this.lyricUl.style.transform =
            "translateY(" + (this.lineNo - this.C_pos) * this.offset + "px)"; //整体向上滚动一行高度
        }
      }
      var lis = this.lyricUl.getElementsByTagName("li"); //歌词数组
      if (this.lineNo > 0) {
        lis[this.lineNo - 1].removeAttribute("class"); //去掉上一行的高亮样式
      }
      lis[this.lineNo].className = "lineHigh"; //高亮显示当前行

      //文字滚动
      if (this.lineNo > this.C_pos) {
        this.lyricUl.style.transform =
          "translateY(" + (this.lineNo - this.C_pos) * this.offset + "px)"; //整体向上滚动一行高度
      }
    },
    lineHigh2() {
      var lis = this.lyricUl.getElementsByTagName("li"); //歌词数组
      for (var i = 0; i < lis.length; i++) {
        var name = lis[i].className;
        if (name != null) lis[i].removeAttribute("class"); //去掉高亮样式
      }
    },
    // 手动拖动滚动条
    seekedFn(curTime) {
      let overflag = true;
      for (let i = 0; i < this.oLRC.ms.length; i++) {
        if (this.oLRC.ms[i].t >= curTime) {
          overflag = false;
          this.lineHigh2(); //取消之前所有高亮
          this.lineNo = i;
          this.lineHigh(true); //高亮当前行
          break;
        }
      }
      // 拖动到最后，没有歌词符合，直接高亮最后一条
      if (overflag) {
        this.lineHigh2(); //取消之前所有高亮
        this.lineNo = this.oLRC.ms.length;
        this.lineHigh(true); //高亮当前行
      }
    },
    // 对歌词的格式进行转换
    createLrcObj(lrc) {
      if (lrc.length == 0) return;
      let lrcs = lrc.split("\n"); //用回车拆分成数组
      let oLRC = this.oLRC;
      for (let i in lrcs) {
        //遍历歌词数组
        lrcs[i] = lrcs[i].replace(/(^\s*)|(\s*$)/g, ""); //去除前后空格
        let t = lrcs[i].substring(
          lrcs[i].indexOf("[") + 1,
          lrcs[i].indexOf("]")
        ); //取[]间的内容
        let s = t.split(":"); //分离:前后文字
        if (isNaN(parseInt(s[0]))) {
          //不是数值
          for (let i in oLRC) {
            if (i != "ms" && i == s[0].toLowerCase()) {
              oLRC[i] = s[1];
            }
          }
        } else {
          //是数值
          let arr = lrcs[i].match(/\[(\d+:.+?)\]/g); //提取时间字段，可能有多个
          let start = 0;
          for (let k in arr) {
            start += arr[k].length; //计算歌词位置
          }
          let content = lrcs[i].substring(start); //获取歌词内容
          if (content.length > 0) {
            for (let k in arr) {
              let t = arr[k].substring(1, arr[k].length - 1); //取[]间的内容
              let s = t.split(":"); //分离:前后文字
              oLRC.ms.push({
                //对象{t:时间,c:歌词}加入ms数组
                t: (parseFloat(s[0]) * 60 + parseFloat(s[1])).toFixed(3),
                c: content,
              });
            }
          }
        }
      }
      oLRC.ms.sort(function (a, b) {
        //按时间顺序排序
        return a.t - b.t;
      });
      // for (let i in oLRC) {
      //   //查看解析结果
      //   console.log(i, ":", oLRC[i]);
      // }
      this.showLRC();
    },
    // 歌词html
    showLRC() {
      let htmlStr = "";
      let oLRC = this.oLRC;
      for (let i in oLRC.ms) {
        //遍历ms数组，把歌词加入列表
        htmlStr += "<li>" + oLRC.ms[i].c + "</li>";
      }
      this.lyrivHtml = htmlStr;
    },
    // 音乐结束
    musicOver() {
      this.lyricUl.style.transform = "translateY(0)";
      this.lineNo = 0;
      this.lyrivHtml = "";
      this.oLRC = {
        ti: "", //歌曲名
        ar: "", //演唱者
        al: "", //专辑名
        by: "", //歌词制作人
        offset: 0, //时间补偿值，单位毫秒，用于调整歌词整体位置
        ms: [], //歌词数组{t:时间,c:歌词}
      };
    },
  },
};
</script>

<style lang="scss" scoped>
.layric-box {
  width: 100%;
  height: 100%;
}
.lyric_area {
  /*歌词显示区域*/
  height: 100%; /*歌词区域高度*/
  overflow: hidden; /*隐藏超出部分*/
}
#lyric {
  /*歌词列表*/
  line-height: 20px; /*行高，这个值要用在歌词滚动距离上*/
  transition-duration: 600ms; /*滚动速度*/
  /deep/li {
    list-style: none;
    text-align: center;
    font-size: 14px;
    color: #333;
  }
}
/deep/#lyric .lineHigh {
  /*高亮行*/
  color: red;
}
</style>